#pragma once

#include <functional>
#include <type_traits>

template<typename R=void>
struct CommCommand
{
private:
    std::function<R()> m_f;

public:
    template<typename F, typename... Args, class = typename std::enable_if<!std::is_member_function_pointer<F>::value>::type>
    void Wrap(F&& f, Args&& ...args)
    {
        m_f = [&] {return f(args...); };
    }

    template<typename R, typename C, typename... DArgs, typename P, typename... Args>
    void Wrap(R(C::* f)(DArgs...) const, P&& p, Args&& ...args)
    {
        m_f = [&, f] {return (*p.*f)(args...); };
    }

    template<typename R, typename C, typename... DArgs, typename P, typename... Args>
    void Wrap(R(C::* f)(DArgs...), P&& p, Args&& ...args)
    {
        m_f = [&, f] {return (*p.*f)(args...); };
    }

    R Excecute()
    {
        return m_f();
    }
};